package com.glodon.paas.document.service.util;

import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.glodon.paas.account.api.bean.User;
import com.glodon.paas.document.biz.ProjectResourceBiz;
import com.glodon.paas.document.constant.DocumentConstant;
import com.glodon.paas.document.dao.FileDao;
import com.glodon.paas.document.dao.ShareDao;
import com.glodon.paas.document.dao.domain.FileInfoEntity;
import com.glodon.paas.exception.PaasServerExceptionFactory;
import com.glodon.paas.exception.i18n.ErrorCode;

@Component
public class DocumentPrivilege {

    @Autowired(required = false)
    private UserProvider userProvider;

    @Autowired
    private FileDao      fileDao;

    @Autowired
    private ShareDao     shareDao;
    
    @Autowired
    private ProjectResourceBiz resourceBiz;

//    private User getUser(String userId) {
//        if (userProvider == null) {
//            return WebServiceUtil.getUser(userId);
//        } else {
//            return userProvider.getUser(userId);
//        }
//    }

    private void checkValue(String userId, String fileId) {
        if (StringUtils.isBlank(userId)) {
            throw PaasServerExceptionFactory.validateException("userId is empty.", null);
        }
        if (StringUtils.isBlank(fileId)) {
            throw PaasServerExceptionFactory.validateException("fileId is empty.", null);
        }
    }

    // for current User
    // public void checkFileOwner(String fileId){
    // if(!isFileOwner(getCurrent().getId(), fileId)){
    // throw
    // PaasServerExceptionFactory.privilegeException("User["+getCurrent().getId()+"] has no privilege to get file["+fileId+"]",
    // null);
    // }
    // }
    //
    // public void checkFileSharer(String fileId){
    // if(!isFileSharer(getCurrent().getId(), fileId)){
    // throw
    // PaasServerExceptionFactory.privilegeException("User["+getCurrent().getId()+"] has no privilege to get file["+fileId+"]",
    // null);
    // }
    // }
    //
    // public void checkFileCreater(String fileId){
    // if(!isFileCreater(getCurrent().getId(), fileId)){
    // throw
    // PaasServerExceptionFactory.privilegeException("User["+getCurrent().getId()+"] has no privilege to get file["+fileId+"]",
    // null);
    // }
    // }
    //
    // public void checkCreaterOwnerSharer(String fileId){
    // String userId = getCurrent().getId();
    // checkValue(userId, fileId);
    // FileInfoEntity file = fileDao.getFile(fileId, null, null);
    // if(file == null){
    // throw PaasServerExceptionFactory.privilegeException("not find file[id:"+fileId+"]", null);
    // }
    // if(userId.equals(file.getCreator()) || userId.equals(file.getOwnerId())){
    // return;
    // }
    // else{
    // if(!isFileSharer(userId, fileId)){
    // throw
    // PaasServerExceptionFactory.privilegeException("User["+getCurrent().getId()+"] has no privilege to get file["+fileId+"]",
    // null);
    // }
    // }
    // }

    public void checkAnyPrivilege(String userId, String resource, boolean owner, boolean sharer) {
        if(owner && isFileOwner(userId, resource)){
            return;
        }
        if(sharer && isFileSharer(userId, resource)){
            return;
        }
        Set<String> pv = resourceBiz.getFilePrivileges(userId, resource, true);
        if (pv.isEmpty()) {
            throw PaasServerExceptionFactory.privilegeException("User[" + userId
                                                                + "] has no privilege to operate reource[" + resource
                                                                + "]", null);
        }
    }
    
    public void checkEnterPrivilege(String userId, String resource, boolean owner, boolean sharer) {
        if(owner && isFileOwner(userId, resource)){
            return;
        }
        if(sharer && isFileSharer(userId, resource)){
            return;
        }
        Set<String> pv = resourceBiz.getFilePrivileges(userId, resource, true);
        if (!pv.contains(DocumentConstant.FILE_ENTER)) {
            throw PaasServerExceptionFactory.privilegeException("User[" + userId + "] has no privilege to enter reource["
                                                                + resource + "]", null);
        }
    }

    public void checkReadPrivilege(String userId, String resource, boolean owner, boolean sharer) {
        if(owner && isFileOwner(userId, resource)){
            return;
        }
        if(sharer && isFileSharer(userId, resource)){
            return;
        }
        Set<String> pv = resourceBiz.getFilePrivileges(userId, resource, true);
        if (!pv.contains(DocumentConstant.FILE_READ) && !pv.contains(DocumentConstant.FILE_INHERIT_READ)) {
            throw PaasServerExceptionFactory.privilegeException("User[" + userId + "] has no privilege to get reource["
                                                                + resource + "]", null);
        }
    }

    public void checkWritePrivilege(String userId, String resource, boolean owner, boolean sharer) {
        if(owner && isFileOwner(userId, resource)){
            return;
        }
        if(sharer && isFileSharer(userId, resource)){
            return;
        }
        Set<String> pv = resourceBiz.getFilePrivileges(userId, resource, true);
        if (!pv.contains(DocumentConstant.FILE_WRITE) && !pv.contains(DocumentConstant.FILE_INHERIT_WRITE)) {
            throw PaasServerExceptionFactory.privilegeException("User[" + userId
                                                                + "] has no privilege to write reource[" + resource
                                                                + "]", null);
        }
    }

    public void checkRemovePrivilege(String userId, String resource, boolean owner, boolean sharer) {
        if(owner && isFileOwner(userId, resource)){
            return;
        }
        if(sharer && isFileSharer(userId, resource)){
            return;
        }
        Set<String> pv = resourceBiz.getFilePrivileges(userId, resource, true);
        if (!pv.contains(DocumentConstant.FILE_DELETE) && !pv.contains(DocumentConstant.FILE_INHERIT_DELETE)) {
            throw PaasServerExceptionFactory.privilegeException("User[" + userId
                                                                + "] has no privilege to remove reource[" + resource
                                                                + "]", null);
        }
    }
    
    public void checkOwnerSharer(String userId, String resource, boolean owner, boolean sharer){
        if(owner && isFileOwner(userId, resource)){
            return;
        }
        if(sharer && isFileSharer(userId, resource)){
            return;
        }
        if(owner || sharer){
            throw PaasServerExceptionFactory.privilegeException("User[" + userId
                                                                + "] has no privilege to operate reource[" + resource
                                                                + "]", null);
        }
    }


    // for assignee
    public boolean isFileOwner(String userId, String fileId) {
        checkValue(userId, fileId);
        // 根目录里的文件，parentId 为 userId。
        if (userId.equals(fileId)) {
            return true;
        }
        FileInfoEntity file = fileDao.getFile(fileId, null, null);
        if (file == null) {
            throw PaasServerExceptionFactory.notFoundException("can not find file[" + fileId + "]", null).setErrorCode(ErrorCode.FILE_NOT_EXIST);
        }
        return userId.equals(file.getOwnerId());
    }

    public boolean isFileSharer(String userId, String fileId) {
        if (StringUtils.isEmpty(fileId)) {
            return false;
        } else {
            if (shareDao.getShareForMe(userId, fileId).size() > 0) {
                return true;
            } else {
                return isFileSharer(userId, fileDao.getParentId(fileId));
            }
        }
    }

    public boolean hasPrivilege(String userId, String resource, boolean enter, boolean read, boolean write, boolean delete, boolean owner, boolean sharer){
        boolean result = (owner && isFileOwner(userId, resource)) || (sharer && isFileSharer(userId, resource));
        if(!result){
            Set<String> pv = resourceBiz.getFilePrivileges(userId, resource, true);
            result = (enter && pv.contains(DocumentConstant.FILE_ENTER)) || (read && pv.contains(DocumentConstant.FILE_READ))
                   ||(write && pv.contains(DocumentConstant.FILE_DELETE)) || (delete && pv.contains(DocumentConstant.FILE_DELETE));
        }
        return result;
    }
    
    public void setFileDao(FileDao fileDao) {
        this.fileDao = fileDao;
    }
    
    public void setShareDao(ShareDao shareDao) {
        this.shareDao = shareDao;
    }
    
    public void setResourceBiz(ProjectResourceBiz resourceBiz) {
        this.resourceBiz = resourceBiz;
    }
    
    public void setUserProvider(UserProvider userProvider) {
        this.userProvider = userProvider;
    }
}
